/**
 * 
 */
package com.maywide.jdp.system.bean;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.maywide.jdp.core.exception.AppException;
import com.maywide.jdp.core.vo.Context;
import com.maywide.jdp.core.vo.Page;
import com.maywide.jdp.dao.Dao;
import com.maywide.jdp.dao.PageQueryTemplate;
import com.maywide.jdp.system.entities.Shortcut;
import com.maywide.jdp.system.vo.ShortcutCheckedTree;
import com.maywide.jdp.system.vo.ShortcutTree;

/**
 * 快捷方式Bean
 * 
 * @author luoyang
 * @version 1.0
 * @since JDK1.6
 */
@Component("shortcutBean")
@Transactional(propagation = Propagation.REQUIRED)
public class ShortcutBeanImpl implements ShortcutBean {
	/**
	 * 基础DAO
	 */
	private Dao dao = null;

	/**
	 * @param dao
	 *            the dao to set
	 */
	@Autowired
	public void setDao(Dao dao) {
		this.dao = dao;
	}

	@Override
	public void insert(Object obj) throws Exception {
		dao.insert(obj);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public void remove(Class clazz, Serializable id) throws Exception {
		Object obj = dao.find(clazz, id);
		dao.remove(obj);
	}

	@Override
	public void update(Object obj) throws Exception {
		dao.update(obj);
	}

	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	@Override
	public Object load(Serializable id) throws Exception {
		Shortcut button = dao.find(Shortcut.class, id);
		return button;
	}

	@Override
	public void lock(String id) throws Exception {
		String jql = "update Button as o set o.active = false where o.id = :id";
		Query query = dao.createQuery(jql);
		query.setParameter("id", id);
		query.executeUpdate();
	}

	@Override
	public void lockAll(String[] ids) throws Exception {
		String hql = "update Shortcut as o set o.active = false where o.id in (:ids)";
		Map<String, Object> conditions = new HashMap<String, Object>();
		conditions.put("ids", ids);
		dao.executeUpdate(hql, conditions);
	}

	@Override
	public void unlock(String id) throws Exception {
		String jql = "update Shortcut as o set o.active = true where o.id = :id";
		Query query = dao.createQuery(jql);
		query.setParameter("id", id);
		query.executeUpdate();
	}

	@Override
	public void unlockAll(String[] ids) throws Exception {
		String hql = "update Shortcut as o set o.active = true where o.id in (:ids)";
		Map<String, Object> conditions = new HashMap<String, Object>();
		conditions.put("ids", ids);
		dao.executeUpdate(hql, conditions);
	}

	@Override
	public void move(String id, String parentID) throws Exception {
		String jql = "update Shortcut as o set o.parent.id = :parentID where o.id = :id";
		Query query = dao.createQuery(jql);
		int row = 0;
		query.setParameter("id", id);
		query.setParameter("parentID", parentID);
		row = query.executeUpdate();
		if (row <= 0)
			throw new AppException("未发生移动操作!");
	}

	@Override
	public void move(List<String> ids, String parentID) throws Exception {
		int row = 0;
		String hql = "update Shortcut as o set o.parent.id = :parentID where o.id in (:ids)";
		Map<String, Object> conditions = new HashMap<String, Object>();
		conditions.put("ids", ids);
		conditions.put("parentID", parentID);
		row = dao.executeUpdate(hql, conditions);
		if (row <= 0)
			throw new AppException("未发生移动操作!");
	}

	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	@Override
	public List<ShortcutTree> tree(Map<String, Object> parameters)
			throws Exception {
		StringBuffer buf = new StringBuffer().append(
				"select distinct o.ID as id,").append("o.SHT_CODE as code,")
				.append("o.SHT_NAME as name,").append("o.SHT_TEXT as text,")
				.append("o.SHT_TAB_INDEX as tabIndex,").append(
						"o.SHT_WIDTH as width,").append(
						"o.SHT_HEIGHT as height,").append(
						"o.SHT_ICON as shortcutIcon,").append(
						"o.SHT_ICON_CLS as shortcutIconCls,").append(
						"o.SHT_SMALL_ICON_CLS as shortcutSmallIconCls,")
				.append("o.SHT_URL as url,").append(
						"o.SHT_PARENT_ID as parentID,").append(
						"o.SHT_DESC as description,").append(
						"o.SHT_ACTIVE as active,").append(
						"decode(sign(count(sub.ID)),1,0,1) as leaf").append(
						" from SYS_SHORTCUT o").append(" left join").append(
						" SYS_SHORTCUT sub on o.ID = sub.SHT_PARENT_ID")
				.append(" INNER JOIN SYS_SHORTCUT_ROLE_REL rel").append(
						" ON o.ID         = rel.SHORTCUT_ID").append(
						" INNER JOIN SYS_ROLE r").append(
						" ON r.ID         = rel.ROLE_ID ");
		if (parameters.containsKey("roleIDs")) {
			String[] roleIDs = (String[]) parameters.get("roleIDs");
			if (roleIDs != null && roleIDs.length > 0) {
				buf.append(" AND r.ID IN (:roleIDs)");
			}
		}
		buf.append(" WHERE");
		if (parameters.containsKey("parentID"))
			buf
					.append(" o.ID IN(SELECT org.ID FROM SYS_SHORTCUT org WHERE org.SHT_PARENT_ID = :parentID AND org.SHT_ACTIVE = 1)");
		else if (parameters.containsKey("rootID"))
			buf.append(" o.ID = :rootID");
		else
			buf
					.append(" o.ID IN(SELECT org.ID FROM SYS_SHORTCUT org WHERE org.SHT_PARENT_ID IS NULL AND org.SHT_ACTIVE = 1)");
		buf.append(" AND");
		buf.append(" o.SHT_ACTIVE = 1 AND o.REMOVED = 0");
		buf
				.append(" group by o.ID,o.SHT_CODE,o.SHT_NAME,o.SHT_TEXT,o.SHT_TAB_INDEX,o.SHT_WIDTH,o.SHT_HEIGHT,o.SHT_ICON,o.SHT_ICON_CLS,o.SHT_SMALL_ICON_CLS,o.SHT_URL,o.SHT_PARENT_ID,o.SHT_DESC,o.SHT_ACTIVE");
		String sql = buf.toString();
		return dao.executeNativeQuery(sql, parameters, ShortcutTree.class,
				"com.maywide.jdp.system.entities.Shortcut.shortcutTree");
	}

	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	@Override
	public List<ShortcutCheckedTree> treeGrid(Map<String, Object> parameters)
			throws Exception {
		StringBuffer buf = new StringBuffer().append(
				"select distinct o.ID as id,").append("o.SHT_CODE as code,")
				.append("o.SHT_NAME as name,").append("o.SHT_TEXT as text,")
				.append("o.SHT_TAB_INDEX as tabIndex,").append(
						"o.SHT_WIDTH as width,").append(
						"o.SHT_HEIGHT as height,").append(
						"o.SHT_ICON as shortcutIcon,").append(
						"o.SHT_ICON_CLS as shortcutIconCls,").append(
						"o.SHT_SMALL_ICON_CLS as shortcutSmallIconCls,")
				.append("o.SHT_URL as url,").append(
						"o.SHT_PARENT_ID as parentID,").append(
						"o.SHT_DESC as description,").append("0 as checked,")
				.append("o.SHT_ACTIVE as active,").append(
						"decode(sign(count(sub.ID)),1,0,1) as leaf").append(
						" from SYS_SHORTCUT o").append(" left join").append(
						" SYS_SHORTCUT sub on o.ID = sub.SHT_PARENT_ID")
				.append(" INNER JOIN SYS_SHORTCUT_ROLE_REL rel").append(
						" ON o.ID         = rel.SHORTCUT_ID").append(
						" INNER JOIN SYS_ROLE r").append(
						" ON r.ID         = rel.ROLE_ID ");
		if (parameters.containsKey("roleIDs")) {
			String[] roleIDs = (String[]) parameters.get("roleIDs");
			if (roleIDs != null && roleIDs.length > 0) {
				buf.append(" AND r.ID IN (:roleIDs)");
			}
		}
		buf.append(" WHERE");
		if (parameters.containsKey("parentID"))
			buf
					.append(" o.ID IN(SELECT org.ID FROM SYS_SHORTCUT org WHERE org.SHT_PARENT_ID = :parentID AND org.SHT_ACTIVE = 1)");
		else if (parameters.containsKey("rootID"))
			buf.append(" o.ID = :rootID");
		else
			buf
					.append(" o.ID IN(SELECT org.ID FROM SYS_SHORTCUT org WHERE org.SHT_PARENT_ID IS NULL AND org.SHT_ACTIVE = 1)");
		buf.append(" AND");
		buf.append(" o.SHT_ACTIVE = 1 AND o.REMOVED = 0");
		buf
				.append(" group by o.ID,o.SHT_CODE,o.SHT_NAME,o.SHT_TEXT,o.SHT_TAB_INDEX,o.SHT_WIDTH,o.SHT_HEIGHT,o.SHT_ICON,o.SHT_ICON_CLS,o.SHT_SMALL_ICON_CLS,o.SHT_URL,o.SHT_PARENT_ID,o.SHT_DESC,o.SHT_ACTIVE");
		String sql = buf.toString();

		List<ShortcutCheckedTree> list = null;
		list = dao.executeNativeQuery(sql, parameters,
				ShortcutCheckedTree.class,
				"com.maywide.jdp.system.entities.Shortcut.shortcutCheckedTree");

		buf = new StringBuffer().append("select distinct o.ID as id,").append(
				"o.SHT_CODE as code,").append("o.SHT_NAME as name,").append(
				"o.SHT_TEXT as text,").append("o.SHT_TAB_INDEX as tabIndex,")
				.append("o.SHT_WIDTH as width,").append(
						"o.SHT_HEIGHT as height,").append(
						"o.SHT_ICON as shortcutIcon,").append(
						"o.SHT_ICON_CLS as shortcutIconCls,").append(
						"o.SHT_SMALL_ICON_CLS as shortcutSmallIconCls,")
				.append("o.SHT_URL as url,").append(
						"o.SHT_PARENT_ID as parentID,").append(
						"o.SHT_DESC as description,").append("1 as checked,")
				.append("o.SHT_ACTIVE as active,").append(
						"decode(sign(count(sub.ID)),1,0,1) as leaf").append(
						" from SYS_SHORTCUT o").append(" left join").append(
						" SYS_SHORTCUT sub on o.ID = sub.SHT_PARENT_ID")
				.append(" INNER JOIN SYS_SHORTCUT_ROLE_REL rel").append(
						" ON o.ID         = rel.SHORTCUT_ID").append(
						" INNER JOIN SYS_ROLE r").append(
						" ON r.ID         = rel.ROLE_ID ");
		if (parameters.containsKey("roleID"))
			buf.append(" AND r.ID = :roleID");
		buf.append(" WHERE");
		if (parameters.containsKey("parentID"))
			buf
					.append(" o.ID IN(SELECT org.ID FROM SYS_SHORTCUT org WHERE org.SHT_PARENT_ID = :parentID AND org.SHT_ACTIVE = 1)");
		else if (parameters.containsKey("rootID"))
			buf.append(" o.ID = :rootID");
		else
			buf
					.append(" o.ID IN(SELECT org.ID FROM SYS_SHORTCUT org WHERE org.SHT_PARENT_ID IS NULL AND org.SHT_ACTIVE = 1)");
		buf.append(" AND");
		buf.append(" o.SHT_ACTIVE = 1 AND o.REMOVED = 0");
		buf
				.append(" group by o.ID,o.SHT_CODE,o.SHT_NAME,o.SHT_TEXT,o.SHT_TAB_INDEX,o.SHT_WIDTH,o.SHT_HEIGHT,o.SHT_ICON,o.SHT_ICON_CLS,o.SHT_SMALL_ICON_CLS,o.SHT_URL,o.SHT_PARENT_ID,o.SHT_DESC,o.SHT_ACTIVE");
		sql = buf.toString();

		List<ShortcutCheckedTree> checkedList = null;
		checkedList = dao.executeNativeQuery(sql, parameters,
				ShortcutCheckedTree.class,
				"com.maywide.jdp.system.entities.Shortcut.shortcutCheckedTree");
		if (checkedList != null && !checkedList.isEmpty()) {
			for (ShortcutCheckedTree checkedShortcut : checkedList) {
				if (list.contains(checkedShortcut)) {
					list.remove(checkedShortcut);
					list.add(checkedShortcut);
				}
			}
		}

		return list;
	}

	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	@Override
	public Page page(int first, int limit, String sort, String dir,
			Map<String, Object> conditions, Map<String, Object> parameters)
			throws Exception {
		Page page = null;
		String queryString = "select o from Shortcut as o inner join o.roles as r";
		String countQueryString = "select count(o.id) from Shortcut as o inner join o.roles as r";
		if (conditions == null)
			conditions = new HashMap<String, Object>();
		if (!conditions.containsKey("parentID"))
			conditions.put("noParentID", null);
		PageQueryTemplate template = new PageQueryTemplate(queryString,
				countQueryString, first, limit, sort, dir);
		page = dao.executePageQuery(template, conditions, null);

		return page;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.maywide.jdp.system.permission.bean.IShortcutBean#getStartShortcuts
	 * (com.maywide.jdp.system.vo.Context)
	 */
	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	@Override
	public List<Shortcut> getStartShortcuts(String parentID, Context context)
			throws Exception {
		String[] roles = context.getRoles();
		if (roles == null)
			return null;

		int n = roles.length;
		String[] roleIDs = new String[n];
		for (int i = 0; i < n; i++) {
			String role = roles[i];
			String[] roleArray = role.split(",");
			roleIDs[i] = roleArray[0];
		}

		Map<String, Object> conditions = new HashMap<String, Object>();
		conditions.put("roleIDs", roleIDs);
		if (parentID == null || parentID.equals("")) {
			conditions.put("noParentID", null);
		} else {
			conditions.put("parentID", parentID);
		}

		String name = "com.maywide.jdp.system.entities.Shortcut.getStartShortcuts";
		return dao.executeNamedQuery(name, conditions, null, Shortcut.class);
	}

	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	@Override
	public List<Shortcut> findShortcuts(String roleID) throws Exception {
		String name = "com.maywide.jdp.system.entities.Shortcut.findShortcuts";
		Map<String, Object> parameters = new HashMap<String, Object>();
		parameters.put("roleID", roleID);
		return dao.executeNamedQuery(name, null, parameters, Shortcut.class);
	}

}
